import sqlite3 as lite
from modele import Client, Parking, Voiture, Placement, Place, Abonnement

class CtrlBdd() :

    def __init__(self, ficBdd = None):
        if ficBdd :
            self.conn = self.seConnecter(ficBdd)
        else :
            self.conn = self.seConnecter()
        self.curseur = self.conn.cursor()
    
    ''' Manipulation bdd '''
        
    def seConnecter(self, ficBdd = None):
        if ficBdd :
            return lite.connect(ficBdd)
        else :
            return lite.connect("bdd.db") # fichier de base
    
    # Lire donnees d'un fichier
    def readData(self):
        f = open('razbase.sql', 'r')
        
        with f:
            data = f.read()
            return data
        
    # Razbase        
    def effacerBdd(self):
          sql = self.readData()
          self.curseur.executescript(sql)
    
    def seDeconnecter(self):
        self.conn.close()
        
    def reinitialisation(self, ctrl):
        self.effacerBdd()
        ctrl.creerParking(self, 4,5, 2.10) #nbNiv, nbPlacesParNiv, prixParPlace   
        
        '''acces1 = ctrl.getAcces1()
        acces2 = ctrl.getAcces2()
        
        
        v1 = ctrl.getVoiture(0)
        v2 = ctrl.getVoiture(1)
        
        v1.demanderPlacement(acces1, self)
        v2.demanderPlacement(acces2, self)
        
        v1.demanderSortie(acces1, self)
        v2.demanderSortie(acces2, self)'''


    ''' Ajout dans bdd '''
        
    def ajouterParking(self, parking):
        nbNiv = parking.getNbNiveaux()
        nbPlaces = parking.getNbPlacesCapacite()
        nbAcces = parking.getNbAcces()
        prixPlace = parking.getPrixPlace()
            
        self.curseur.execute("""insert into parking(nbNiveaux, nbPlaces, prixPlace, nbAcces) 
                values (?, ?, ?, ?)""", (nbNiv, nbPlaces, prixPlace, nbAcces))

        self.conn.commit()
    
    def ajouterNiveau(self, niveau):
        num = niveau.getNumNiveau()
        nbPlaces = niveau.getNbPlaces()
        idParking = 1 # on a qu un seul parking
        
        self.curseur.execute("""insert into niveau(idN, nbPlaces, parking) 
                values (?, ?, ?)""", (num, nbPlaces, idParking))

        self.conn.commit()
    
    
    def ajouterPlace(self, place):
        num = place.getNumPlace()
        long = place.getLongueur()
        larg = place.getLargeur()
        estLibre = True
        niveau = place.getNumNiveau()
        
        self.curseur.execute("""insert into place(numero, longueur, largeur, estLibre, niveau) 
                values (?, ?, ?, ?, ?)""", (num, long, larg, estLibre, niveau))

        self.conn.commit()    
    
    def ajouterVoiture(self, voiture):
        immatriculation = voiture.getImmatriculation()
        longueur = voiture.getLongueur()
        largeur = voiture.getLargeur()
        estGaree = voiture.getEstGaree()
        idProp = 0 #inconnu de base

        self.curseur.execute("""insert into voiture(immatriculation, longueur, largeur, estGaree, proprietaire) 
                values (?, ?, ?, ?, ?)""", (immatriculation, longueur, largeur, estGaree, idProp))
        self.conn.commit()
        
        return self.curseur.lastrowid
    
    def ajouterClient(self, client):
        nom = client.getNom()
        prenom = client.getPrenom()
        adresse = client.getAdresse()
        mail = client.getMail()
        tel = client.getTel()
        nbFrequentations = client.getNbFrequentations()
        
        if client.getAbonnement() :
            abonnement = client.getAbonnement().getId()
        else :
            abonnement = 0
            
        self.curseur.execute("""insert into client(nomC, prenomC, adresseC, mailC, telC, abonnement, nbFrequentations) 
                values (?, ?, ?, ?, ?, ?, ?)""", (nom, prenom, adresse, mail, tel, abonnement, nbFrequentations))
        
        id = self.curseur.lastrowid
        client.setId(id)
        self.curseur.execute("""UPDATE voiture SET proprietaire = ? WHERE proprietaire = 0""", (id,))

        self.conn.commit()
        
    def ajouterPlacement(self, voiture, placement):
        place = placement.getPlace()
        
        if voiture.getEstGaree() == False :
            self.curseur.execute("""select idVoiture from voiture where immatriculation like ? LIMIT 1""", (voiture.getImmatriculation(),))
            retourIdV = self.curseur.fetchone()
            idVoiture = retourIdV[0]
            
            self.curseur.execute("""select idPlace from place where numero like ? LIMIT 1""", (place.getNumPlace(),))
            retourIdP = self.curseur.fetchone()
            idPlace = retourIdP[0]
        
            self.curseur.execute("""insert into placement(idPlace, idVoiture, dateEntree, dateSortie, typePaiement) 
                values (?, ?, ?, ?, ?)""", (idPlace, idVoiture, placement.getDateEntree(), 'null', placement.getTypePaiement()))
            self.conn.commit()
       
    def ajouterAbonnement(self, lib, prix):
        
        self.curseur.execute("""insert into abonnement(libelle, prix) values (?, ?)""", (lib, str(prix)))

        self.conn.commit() 
            
    def libererPlace(self, place, voiture):
        self.curseur.execute("""UPDATE place SET estLibre = 1 WHERE numero like ?""", (place.getNumPlace(),))
        self.conn.commit()
     
    def libererPlacement(self, voiture):   
        placement = voiture.getPlacement()
        place = placement.getPlace()
        
        self.curseur.execute("""select idVoiture from voiture where immatriculation like ? LIMIT 1""", (voiture.getImmatriculation(),))
        retourIdV = self.curseur.fetchone()
        idVoiture = retourIdV[0]
        
        self.curseur.execute("""select idPlace from place where numero like ? LIMIT 1""", (place.getNumPlace(),))
        retourIdP = self.curseur.fetchone()
        idPlace = retourIdP[0]
        
        self.curseur.execute("""UPDATE placement SET dateSortie = ? WHERE idPlace = ? and idVoiture = ? and dateSortie like 'null'""", (placement.getDateSortie(), idPlace, idVoiture))
        self.conn.commit()
    
    def allouerPlace(self, place):
        self.curseur.execute("""UPDATE place SET estLibre = 0 WHERE numero like ?""", (place.getNumPlace(),))
        self.conn.commit()
    
    def garer(self, voiture):
        self.curseur.execute("""UPDATE voiture SET estGaree = 1 WHERE immatriculation like ?""", (voiture.getImmatriculation(),))
        self.conn.commit()
    
    def sortir(self, voiture):
        self.curseur.execute("""UPDATE voiture SET estGaree = 0 WHERE immatriculation like ?""", (voiture.getImmatriculation(),))
        self.conn.commit()
    
    def updateAbonnement(self, client, nouvNumAbo):
        id = client.getId()
        contrat = client.getAbonnement().getListeContrats()[-1]
        dateDebut = contrat.getDateDebut()
        dateFin = contrat.getDateFin()
        Placement
        self.curseur.execute("""UPDATE client SET abonnement = ? WHERE idC = ?""", (nouvNumAbo, id,))
        self.curseur.execute("""insert into contrat(idClient, idAbo, dateDebut, dateFin) values (?, ?, ?, ?)""", (id, nouvNumAbo, dateDebut, dateFin))
        
        self.conn.commit()
    
    def updatePlacementPaiement(self, voiture, nouvTypePaiement):
        placement = voiture.getPlacement()
        place = placement.getPlace()
        
        self.curseur.execute("""select idVoiture from voiture where immatriculation like ? LIMIT 1""", (voiture.getImmatriculation(),))
        retourIdV = self.curseur.fetchone()
        idVoiture = retourIdV[0]
        
        self.curseur.execute("""select idPlace from place where numero like ? LIMIT 1""", (place.getNumPlace(),))
        retourIdP = self.curseur.fetchone()
        idPlace = retourIdP[0]
        
        self.curseur.execute("""UPDATE placement SET typePaiement = ? WHERE idPlace = ? and idVoiture = ? and dateSortie like 'null'""", (nouvTypePaiement, idPlace, idVoiture))
        self.conn.commit()
        
        
    ''' getter '''
        
    def getIdVoiture(self, image):
        self.curseur.execute("""select idVoiture from voiture where immatriculation like ? LIMIT 1""", (image.getImmatriculation(),))
        retourId = self.curseur.fetchone()
        if retourId == None :
            return 0
        else :
            return retourId[0]
    
    def getIdNewClient(self):
        self.curseur.execute("""select count(*) + 1 from client""")
        retourId = self.curseur.fetchone()
        
        return retourId[0]
    
    def getInfosPlaceIdeale(self, image):
        long = image.getLongueur()
        larg = image.getLargeur()
        
        self.curseur.execute("""select niveau, numero from place where estLibre == 1 and longueur >= ? and largeur >= ? order by idPlace ASC LIMIT 1""", (long, larg,))
        retourInfos = self.curseur.fetchone()
  
        return retourInfos
    
    def getInfosPlaceSuperAbo(self, image):
        id = self.getIdVoiture(image)
        self.curseur.execute("""select idPlace from placement where idVoiture = ? LIMIT 1""", (id,))
        retourIdPlace = self.curseur.fetchone()
        idPlace = retourIdPlace[0]
        
        self.curseur.execute("""select niveau, numero from place where idPlace = ?""", (idPlace,))
        retourInfos = self.curseur.fetchone()
  
        return retourInfos
        
     # On teste la persistance
    def afficherClasseVoiture(self):
        for ligne in self.curseur.execute("""select * from voiture"""):
            print(ligne)
    
    
    def renseignerStatutClient(self, voiture, idVoiture, listeAbo):
        self.curseur.execute("""select proprietaire from voiture where idVoiture = ?""", (idVoiture,))
        retourId = self.curseur.fetchone()
        idProp = retourId[0]
      
        if idProp == 0 :
            proprietaire = voiture.getProprietaire()
            self.ajouterClient(proprietaire)
        else :
            self.curseur.execute("""select * from client where idC = ?""", (idProp,))
            retour = self.curseur.fetchone()
            idAbo = retour[6]
            
            if idAbo == 0 :
                typeAbo = False
            else :
                for abo in listeAbo :
                    if abo.getId() == idAbo :
                        typeAbo = abo
            
            proprietaire = Client.Client(voiture, retour[1], retour[2], retour[3], retour[4], retour[5], retour[7], retour[0], typeAbo) 
            voiture.setProprietaire(proprietaire)         

            
        return proprietaire
    
    def renseignerParking(self):
        self.curseur.execute("""select * from parking where idP = 1""")
        retour = self.curseur.fetchone()
        
        parking = Parking.Parking(self, retour[1], retour[2], retour[3], True)

        return parking
    
        '''def renseignerPlacement(self, place):
        numero = place.getNumPlace()

        self.curseur.execute("""select idPlace from place where numero like ?""", (numero,))
        retour = self.curseur.fetchone()
        idPlace = retour[0]
        
        self.curseur.execute("""select * from placement where idPlace = ? ORDER BY idPlacement DESC LIMIT 1""", (idPlace,))
        retour = self.curseur.fetchone()
        
        placement = Placement.Placement(place, retour[3])
        
        return placement'''

        
    def renseignerPlacementVoiture(self, parking, voiture, id):
        self.curseur.execute("""select * from placement where idVoiture = ? ORDER BY idPlacement DESC LIMIT 1""", (id,))
        retour = self.curseur.fetchone()
        
        self.curseur.execute("""select * from place where idPlace = ?""", (retour[1],))
        retour2 = self.curseur.fetchone()
        
        numNiv = retour2[5]
        numPlace = retour2[1]
        
        place = parking.getPlace(numNiv, numPlace) 
        placement = Placement.Placement(place, retour[3], retour[5])

        return placement
    
    def renseignerListeVoitures(self):
        listeVoitures = []
        for rowV in self.curseur.execute("""select * from voiture"""):
            listeVoitures.append(rowV)
        
        return listeVoitures
    
    def renseignerListePlaces(self, numNiv):
        listePlacesParNiv = []
        for row in self.curseur.execute("""select * from place where niveau = ?""", (numNiv,)):
            listePlacesParNiv.append(row)
        
        return listePlacesParNiv
    
    def renseignerListeAbonnements(self):
        listeAbo = []
        for row in self.curseur.execute("""select * from abonnement"""):
            listeAbo.append(row)

        return listeAbo
    
    def getInfosFrequentations(self):
        listeClients = []
        listeTamp = []
        for row in self.curseur.execute("""select * from client order by nbFrequentations DESC"""):
            listeTamp.append(row)
        
        for row in listeTamp:
            self.curseur.execute("""select libelle from abonnement where idA = ?""", (row[6],))
            abo = self.curseur.fetchone()
            
            tamp = row[1:3] + abo + row[6:7]
            listeClients.append(tamp)
        
        return listeClients
    
    def getNbAbo(self):
        self.curseur.execute("""select count(idC) from client where abonnement = 1""")
        nb = self.curseur.fetchone()
        
        return nb[0]
    
    def getNbSuperAbo(self):
        self.curseur.execute("""select count(idC) from client where abonnement = 2""")
        nb = self.curseur.fetchone()
        
        return nb[0]
    
    def getNonAbo(self):
        self.curseur.execute("""select count(idC) from client where abonnement = 0""")
        nb = self.curseur.fetchone()
        
        return nb[0]
    
    def getInfosContrats(self):
        listeContrats = []
        listeTamp = []
        for row in self.curseur.execute("""select * from contrat"""):
            listeTamp.append(row)
        
        for row in listeTamp:
            self.curseur.execute("""select nomC from client where idC = ?""", (row[1],))
            nom = self.curseur.fetchone()
            self.curseur.execute("""select libelle from abonnement where idA = ?""", (row[2],))
            abo = self.curseur.fetchone()
            
            tamp = row[:1] + nom + abo + row[3:]
            listeContrats.append(tamp)
        
        return listeContrats
    
    def getInfosParking(self):
        listeInfos = []
        for row in self.curseur.execute("""select * from parking"""):
            listeInfos.append(row)
            
        return listeInfos
    
    def getInfosPlacement(self):
        listePlacements = []
        listeTamp = []
        
        for row in self.curseur.execute("""select * from placement"""):
            listeTamp.append(row)
        
        for row in listeTamp:
            self.curseur.execute("""select numero from place where idPlace = ?""", (row[1],))
            num = self.curseur.fetchone()
            self.curseur.execute("""select immatriculation from voiture where idVoiture = ?""", (row[2],))
            immat = self.curseur.fetchone()
                
            tamp = row[:1] + num + immat + row[3:]
            listePlacements.append(tamp)
        
        return listePlacements

    ''' autres actions '''
    
    def verifierCarte(self, client):
        return True # vrai verif a faire... on sait que ca sera bon
        #self.curseur.execute("""select * from client where idC = ?""", (client.getId()))
        #proprietaire = self.curseur.fetchone() 
        
    def incrementerNbFreq(self, client):
        self.curseur.execute("""UPDATE client SET nbFrequentations = ? WHERE idC = ?""", (client.getNbFrequentations(), client.getId(),))
        self.conn.commit()
    
   
    